/* ***** BEGIN LICENSE BLOCK *****
 *   Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Seoprofesional
 *
 * The Initial Developer of the Original Code is
 * Petr Blahoš.
 * Portions created by the Initial Developer are Copyright (C) 2009
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * 
 * ***** END LICENSE BLOCK ***** */



var sbView = {
link_comparator: {
  nofollow: function(domain, x)  {   return -1!=x.rel.toLowerCase().indexOf("nofollow"); },
  all: function(domain, x)  {  return true;        },
  internal: function(domain, x)   {  return SeoprofesionalTools.get_domain(x.href)==domain;    },
  external: function(domain, x)   {  return !sbView.link_comparator.internal(domain, x);  },
  _x_sentinel_0: 0
},
whitelist : [],
visibleData: [],
init: function() {
  this.browser = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
     .getInterface(Components.interfaces.nsIWebNavigation)
     .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
     .rootTreeItem
     .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
     .getInterface(Components.interfaces.nsIDOMWindow).gBrowser;

  this.strings = document.getElementById("seop-strings");
  this.whitelist = sbView.seopdb.get_whitelist();
  this.visibleData = [];
  this.hllist = document.getElementById("hllist");
  this.hlsplitter = document.getElementById("hlsplitter");
  for (var i = 0;i<this.whitelist.length;i++) {
    this.visibleData.push([ this.whitelist[i], true, false ]);
  }
},

treeBox: null,  
selection: null,  

get rowCount()                     { return this.visibleData.length; },  
setTree: function(treeBox)         { this.treeBox = treeBox; },  
getCellText: function(idx, column) {
  if (this.isContainer(idx)) {
    if ("url"==column.id)    return this.visibleData[idx][0];
    return "1";
  }
  var par = this.getParentIndex(idx);
  var root = this.visibleData[par][0];
  if ("url"==column.id) {
    var ret = this.visibleData[idx][0].substring(this.visibleData[par][0].length);
    if (0==ret.length)  return "."
    return ret;
  }
  return "2";
},
isContainer: function(idx)         { return sbView.visibleData[idx][1]; },  
isContainerOpen: function(idx)     { return this.visibleData[idx][2]; },  
isContainerEmpty: function(idx)    { return false; },  
isSeparator: function(idx)         { return false; },  
isSorted: function()               { return false; },  
isEditable: function(idx, column)  { return false; },  

getParentIndex: function(idx) {  
  if (this.isContainer(idx)) return -1;  
  for (var t = idx - 1; t >= 0 ; t--) {  
    if (this.isContainer(t)) return t;  
  }  
},  
getLevel: function(idx) {  
  if (this.isContainer(idx)) return 0;  
  return 1;  
},  
hasNextSibling: function(idx, after) {
  var thisLevel = this.getLevel(idx);  
  for (var t = after + 1; t < this.visibleData.length; t++) {  
    var nextLevel = this.getLevel(t);  
    if (nextLevel == thisLevel) return true;  
    if (nextLevel < thisLevel) break;  
  }  
  return false;  
},
toggleOpenState: function(idx) {
  var item = this.visibleData[idx];  
  if (!item[1]) return;  

  if (item[2]) {
    item[2] = false;  

    var thisLevel = this.getLevel(idx);  
    var deletecount = 0;  
    for (var t = idx + 1; t < this.visibleData.length; t++) {  
      if (this.getLevel(t) > thisLevel) deletecount++;  
      else break;  
    }  
    if (deletecount) {  
      this.visibleData.splice(idx + 1, deletecount);  
      this.treeBox.rowCountChanged(idx + 1, -deletecount);  
    }  
  }  
  else {  
    item[2] = true;  

    var root = this.visibleData[idx][0];  
    var toinsert = sbView.seopdb.get_sub(root);
    for (var i = 0; i < toinsert.length; i++) {  
      this.visibleData.splice(idx + i + 1, 0, [toinsert[i], false]);  
    }  
    this.treeBox.rowCountChanged(idx + 1, toinsert.length);  
  }
  this.treeBox.invalidateRow(idx);  
},  

getImageSrc: function(idx, column) {
  var url = this.visibleData[idx][0];
  var iconURL = "chrome://browser/skin/Bookmarks-folder.png";
  try {
    var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
    var historyService = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService);

    var options = historyService.getNewQueryOptions();
    var query = historyService.getNewQuery();

    options.resultType = options.RESULTS_AS_URI;
    query.uri = ioService.newURI(url, null, null);

    var result = historyService.executeQuery(query, options);
    result.root.containerOpen = true;
    try {
      iconURL = result.root.getChild(0).icon;
    } catch (e) {
    }
    result.root.containerOpen = false;
  } catch (e) {
  }
  return iconURL;
},
getProgressMode : function(idx,column) {},
getCellValue: function(idx, column) {},
cycleHeader: function(col, elem) {},
selectionChanged: function() {},
cycleCell: function(idx, column) {},
performAction: function(action) {},

click: function(tree, ev) {
  if (2==ev.button) {
    return ;
  }
  var tbo = tree.treeBoxObject;
  var row = { }, col = { }, obj = { };
  tbo.getCellAt(ev.clientX, ev.clientY, row, col, obj);
  if (-1==row.value) {
    return ;
  }
  if (this.isContainer(row.value)) {
    return ;
  }
  this.browser.loadURI(this.visibleData[row.value][0], null, null);
},
counter: 0,
tt_uri: "",
tipShowing: function(ev) {
  var tbo = document.getElementById("seop-uri-tree").treeBoxObject;
  var row = { }, col = { }, obj = { };
  tbo.getCellAt(ev.clientX, ev.clientY, row, col, obj);
  if (-1==row.value) {
    return false;
  }
  this.tt_uri = this.visibleData[row.value][0];
  if (!sbView.seopdb.is_whitelisted(this.tt_uri)) {
    return false;
  }
  return true;
},
tipShown: function(ev) {
  SeoprofesionalTools.set_attr("seop-tip-footer", "value", sbView.tt_uri);
  SeoprofesionalTools.set_attr("seop-tip-frame", "src", "chrome://seoprofesional/content/plot.html?" + this.counter++ + "&uri=" + sbView.tt_uri);
  return true;
},
prepare_menu: function(ev) {
  var row = document.getElementById("seop-uri-tree").currentIndex;
  if (-1==row) {
    return false;
  }
  if (sbView.isContainer(row)) {
    SeoprofesionalTools.set_attr("st-forget", "hidden", true);
  } else {
    SeoprofesionalTools.set_attr("st-forget", "hidden", false);
  }
  return true;
},
forget: function(ev) {
  var row = document.getElementById("seop-uri-tree").currentIndex;
  if (-1==row) {
    return ;
  }
  var uri = sbView.visibleData[row][0];
  sbView.seopdb.forget_record(uri);
  row = sbView.getParentIndex(row);
  sbView.toggleOpenState(row);
  sbView.toggleOpenState(row);
},
refresh: function(ev) {
  var row = document.getElementById("seop-uri-tree").currentIndex;
  if (-1==row) {
    return ;
  }
  var uri = sbView.visibleData[row][0];
  if (sbView.isContainer(row)) {
    var uris = sbView.seopdb.get_sub(uri);
    for (var j = 0; j < uris.length; j++) {
      for (var i = 0;i<sbView.seop_global.fetchers.length;i++) {
        var f = sbView.seop_global.fetchers[i];
        if (f.enabled) {
          sbView.seop_global.fetchers[i].fetch(null, uris[j]);
        }
      }
    }
    return;
  }
  for (var i = 0;i<sbView.seop_global.fetchers.length;i++) {
    var f = sbView.seop_global.fetchers[i];
    if (f.enabled) {
      sbView.seop_global.fetchers[i].fetch(null, uri);
    }
  }
  
},
unhilight_all: function() {
  for (var i = 0;i<sbView.browser.contentWindow.frames.length; i++) {
    try {
      sbView.unhilight_win(sbView.browser.contentWindow.frames[i], Ci.nsISelectionController.SELECTION_FIND);
    } catch (e) {
      SeoprofesionalTools.LOG("frame:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
    }
  }
  try {
    sbView.unhilight_win(sbView.browser.contentWindow, Ci.nsISelectionController.SELECTION_FIND);
  } catch (e) {
    SeoprofesionalTools.LOG("main:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
  }
  sbView.hllist.setAttribute("hidden", true);
  sbView.hlsplitter.setAttribute("hidden", true);
},
unhilight_win: function(win, type) {
        var docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
                                .getInterface(Ci.nsIWebNavigation)
                                .QueryInterface(Ci.nsIDocShell);

        var controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsISelectionDisplay)
                                   .QueryInterface(Ci.nsISelectionController);
  var find_selection = controller.getSelection(type);
  find_selection.removeAllRanges();
},
set_hllist: function(items) {
  while(null!=sbView.hllist.firstChild) {
    sbView.hllist.removeChild(sbView.hllist.firstChild);
  }
  for (var i = 0;i<items.length; i++) {
    var item = document.createElement("listitem");
    item.setAttribute("label", "" + (1+i) + ": " + items[i][0]);
    item.setAttribute("index", i);
    sbView.hllist.appendChild(item);
  }
  sbView.hl_ranges = items;
  sbView.hllist.setAttribute("hidden", false);
  sbView.hlsplitter.setAttribute("hidden", false);
},
hllist_sel: function(el, ev) {
  var si = el.selectedItem;
  if (null==si) {
    return ;
  }
  for (var i = 0;i<sbView.browser.contentWindow.frames.length; i++) {
    try {
      sbView.unhilight_win(sbView.browser.contentWindow.frames[i], Ci.nsISelectionController.SELECTION_NORMAL);
    } catch (e) {
      SeoprofesionalTools.LOG("frame:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
    }
  }
  try {
    sbView.unhilight_win(sbView.browser.contentWindow, Ci.nsISelectionController.SELECTION_NORMAL);
  } catch (e) {
    SeoprofesionalTools.LOG("win:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
  }

  var i = 1*si.getAttribute("index");
  var item = sbView.hl_ranges[i];

  item[2].getSelection(Ci.nsISelectionController.SELECTION_NORMAL).addRange(item[1]);
  item[2].scrollSelectionIntoView(Ci.nsISelectionController.SELECTION_NORMAL, Ci.nsISelectionController.SELECTION_ANCHOR_REGION, false);
},
hilight_links: function () {
  var input = document.getElementById("hllink").value;
  var include = sbView.link_comparator[input];
  var refs = [];
  for (var i = 0;i<sbView.browser.contentWindow.frames.length; i++) {
    try {
      sbView.hilight_links_doc(refs, include, sbView.browser.contentWindow.frames[i]);
    } catch (e) {
      SeoprofesionalTools.LOG("frame:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
    }
  }
  try {
    sbView.hilight_links_doc(refs, include, sbView.browser.contentWindow);
  } catch (e) {
    SeoprofesionalTools.LOG("main:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
  }
  sbView.set_hllist(refs);
},
hilight_links_doc: function(refs, include, win) {
  var doc = win.document;
  if (!doc || !(doc instanceof HTMLDocument)) {
    return ;
  }
  var docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
                                .getInterface(Ci.nsIWebNavigation)
                                .QueryInterface(Ci.nsIDocShell);

  var controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsISelectionDisplay)
                                   .QueryInterface(Ci.nsISelectionController);
  var find_selection = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);

  find_selection.removeAllRanges();

  var domain = SeoprofesionalTools.get_domain(doc.baseURIObject.spec);
  for (var i = 0; i<doc.links.length;i++) {
    if (include(domain, doc.links[i])) {
      var range = doc.createRange();
      try {
        range.setStart(doc.links[i], 0);
        range.setEnd(doc.links[i], 1);
        find_selection.addRange(range);
        refs.push([ doc.links[i].href, range, controller ]);
      } catch (e) {
        SeoprofesionalTools.LOG("==> range error!!!:" + range);
      }
    }
  }
  controller.setDisplaySelection(Ci.nsISelectionController.SELECTION_ON);
},
hilight_kw: function() {
  var input = document.getElementById("hlkw").value;
  var refs = [];
  for (var i = 0;i<sbView.browser.contentWindow.frames.length; i++) {
    try {
      sbView.hilight_kw_doc(refs, input, sbView.browser.contentWindow.frames[i]);
    } catch (e) {
      SeoprofesionalTools.LOG("frame:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
    }
  }
  try {
    sbView.hilight_kw_doc(refs, input, sbView.browser.contentWindow);
  } catch (e) {
    SeoprofesionalTools.LOG("main:" + sbView.browser.contentWindow.frames[i].document.baseURIObject.spec + " exception " + e);
  }
  sbView.set_hllist(refs);
},
hilight_kw_doc: function(refs, input, win) {
  var doc = win.document;
  if (!doc || !(doc instanceof HTMLDocument)) {
    return ;
  }
  var docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
        .getInterface(Ci.nsIWebNavigation)
        .QueryInterface(Ci.nsIDocShell);
  var controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
           .getInterface(Ci.nsISelectionDisplay)
           .QueryInterface(Ci.nsISelectionController);
  var find_selection = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);

  find_selection.removeAllRanges();
  if (""==input) {
    return;
  }
  var body = doc.body;
  var count = body.childNodes.length;
  var searchRange = doc.createRange();
  var startPt = doc.createRange();
  var endPt = doc.createRange();

  searchRange.setStart(body, 0);
  searchRange.setEnd(body, count);

  startPt.setStart(body, 0);
  startPt.setEnd(body, 0);
  endPt.setStart(body, count);
  endPt.setEnd(body, count);

  var retRange = null;
  var finder = Cc["@mozilla.org/embedcomp/rangefind;1"].createInstance().QueryInterface(Ci.nsIFind);
  finder.caseSensitive = false;

  while((retRange = finder.Find(input, searchRange, startPt, endPt))) {
    startPt = retRange.endContainer.ownerDocument.createRange();
    startPt.setStart(retRange.endContainer, retRange.endOffset);
    startPt.setEnd(retRange.endContainer, retRange.endOffset);

    find_selection.addRange(retRange);
    r2 = retRange.cloneRange();
    if (r2.startOffset>5) {
      r2.setStart(r2.startContainer, r2.startOffset-5);
    } else {
      r2.setStart(r2.startContainer, 0);
    }
    r2.setEndAfter(r2.endContainer);
    refs.push([ "..." + r2 + "...", retRange, controller ]);
  }
  controller.setDisplaySelection(Ci.nsISelectionController.SELECTION_ON);
},
_x_sentinel_0: 0
};  

Components.utils.import("resource://seoprofesional/seopdb.jsm", sbView);

window.addEventListener("load", function(e) { 
    sbView.init();
    document.getElementById('seop-uri-tree').view = sbView;
}, false);


